package br.usp.trabalho.sd.master;

import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashSet;
import java.util.Set;



public class NodeListManager
{
    private static final String FILENAME_NODE_LIST = "nodeList.bin";

    private Set<ServerNode> mNodeList;
    private File            mNodeListFile;


    public NodeListManager() throws IOException
    {
        mNodeList = new HashSet<>();

        mNodeListFile = new File(FILENAME_NODE_LIST);
        if (mNodeListFile.exists())
        {
            loadNodeList();
        }
        else
        {
            mNodeListFile.createNewFile();
        }
    }


    public synchronized void saveNodeList() throws IOException
    {
        ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(mNodeListFile));
        try
        {
            for (ServerNode node : mNodeList)
            {
                outputStream.writeObject(node);
            }
        }
        finally
        {
            outputStream.close();
        }
    }

    public synchronized void loadNodeList() throws FileNotFoundException, IOException
    {
        ObjectInputStream input = new ObjectInputStream(new FileInputStream(mNodeListFile));
        try
        {
            boolean hasObjects = true;
            while (hasObjects)
            {
                try
                {
                    mNodeList.add((ServerNode) input.readObject());
                }
                catch (EOFException e)
                {
                    hasObjects = false;
                }
                catch (ClassNotFoundException e)
                {
                    e.printStackTrace();
                }
            }
        }
        finally
        {
            input.close();
        }
    }

    public synchronized boolean addNewNodeToList(String name, String ip) throws IOException
    {
        boolean result = mNodeList.add(new ServerNode(name, ip));
        if (result)
        {
            saveNodeList();
        }
        return result;
    }

    public synchronized ServerNode getNodeInfo(String name)
    {
        for (ServerNode node : mNodeList)
        {
            if (node.name.equals(name))
            {
                return node;
            }
        }

        return null;
    }

    public synchronized boolean removeNodeFromList(String name) throws IOException
    {
        for (ServerNode node : mNodeList)
        {
            if (node.name.equals(name))
            {
                // Remove the node from the list
                mNodeList.remove(node);

                // Save the new state of the list
                saveNodeList();

                return true;
            }
        }

        return false;
    }

    public synchronized void setNodeAsBusy(String name) throws IOException
    {
        for (ServerNode node : mNodeList)
        {
            if (node.name.equals(name))
            {
                node.setBusy(true);
                saveNodeList();
            }
        }
    }
    public synchronized void freeNode(String name) throws IOException
    {
        for (ServerNode node : mNodeList)
        {
            if (node.name.equals(name))
            {
                node.setBusy(false);
                saveNodeList();
            }
        }
    }
}
